#include "gameplay.h"

//-----------------------------
gamePlay::gamePlay(building* _myBuilding,soundManager* _mySoundManager)
{

	mySoundManager = _mySoundManager;
	myBuilding = _myBuilding;
	resetGame();
}
//-----------------------------
// reset all
void gamePlay::resetGame()
{
	k = 0;
	
	pointsTeamA= 0;
	pointsTeamB = 0;
	gameOver = ' ';
	gameOverSnake = 0;
	speedRefresh = 5;
	isGameOver = false;
	isGameStart = false;
	startAnimation = false;
	startAnimation_CountDown = 0;
	// sound
	mySoundManager->endStop();
	mySoundManager->preparation();
	L.clear();
}

//-----------------------------
void gamePlay::startGame()
{
	startAnimation = true;
	startAnimation_CountDown = 50;
	mySoundManager->start();
	mySoundManager->preparationStop();
}
//-----------------------------

void  gamePlay::addBlock(char team, int posX, int posY)
{
	if(isGameStart)
	{
		block myBlock(team, posX, posY);
		L.push_back( myBlock );
	}
}

//-----------------------------

void gamePlay::collisions()
{
	list<block>::iterator i;
	for(i=L.begin(); i != L.end();)
	{
		if( (*i).team == 'c' && (*i).lifeCounter <= 10 && (*i).lifeCounter >= 0)
		{ 
			int move = 1;
			
			if((*i).lifeCounter == 10 || (*i).lifeCounter ==9 )move = 1;
			if((*i).lifeCounter == 8 || (*i).lifeCounter ==7 )move = 2;
			if((*i).lifeCounter == 6 || (*i).lifeCounter ==5)move = 3;
			if((*i).lifeCounter == 4 || (*i).lifeCounter ==3)move = 4;
			if((*i).lifeCounter == 2 || (*i).lifeCounter ==1 || (*i).lifeCounter ==0)move = 5;
			
			int posXNeg = (*i).x-move;
			if(posXNeg<0) posXNeg = posXNeg+40;
			int posXPos = (*i).x+move;
			if(posXPos>39) posXPos = posXPos-40;

			if( getWindowMap((*i).y-move,posXPos)!=-1 )myBuilding->setWindowColor( getWindowMap((*i).y-move,posXPos), 255,255,255);
			if( getWindowMap((*i).y+move,posXPos)!=-1 )myBuilding->setWindowColor( getWindowMap((*i).y+move,posXPos), 255,255,255);		
			if( getWindowMap((*i).y+move,posXNeg)!=-1 )myBuilding->setWindowColor( getWindowMap((*i).y+move,posXNeg), 255,255,255);
			if( getWindowMap((*i).y-move,posXNeg)!=-1 )myBuilding->setWindowColor( getWindowMap((*i).y-move,posXNeg), 255,255,255);					
		}	
		++i;
	}
}

//-----------------------------

void  gamePlay::update()
{
	
	bool collision = false;
	bool points = false;
	
		for(int h=0; h < 18; h++) 
		{
			myBuilding->setWindowColor( getWindowMap(18-h,5), 20,20,200);
			myBuilding->setWindowColor( getWindowMap(18-h,4), 20,20,200);
		}

		// State 1]: small animation to start
		if(startAnimation && !isGameStart){
			//cout << h/40<< " - "<< h%40 << endl;
			startAnimation_CountDown--;

			int h= (int)((float)startAnimation_CountDown/2.6f);
			//myBuilding->setWindowColor( getWindowMap(18-h,4), 150,150,150);
			//myBuilding->setWindowColor( getWindowMap(18-h,5), 150,150,150);
			// 3
			if(startAnimation_CountDown < 45 && startAnimation_CountDown >=30 ){
				myBuilding->setWindowColor( getWindowMap(2,4), 255,255,255);
				myBuilding->setWindowColor( getWindowMap(2,5), 255,255,255);
				myBuilding->setWindowColor( getWindowMap(3,5), 255,255,255);
				myBuilding->setWindowColor( getWindowMap(4,4), 255,255,255);
				myBuilding->setWindowColor( getWindowMap(4,5), 255,255,255);
				myBuilding->setWindowColor( getWindowMap(5,5), 255,255,255);
				myBuilding->setWindowColor( getWindowMap(6,4), 255,255,255);
				myBuilding->setWindowColor( getWindowMap(6,5), 255,255,255);
			// 2
			}else if(startAnimation_CountDown < 30 && startAnimation_CountDown >=15 ){
				myBuilding->setWindowColor( getWindowMap(7,4), 255,255,255);
				myBuilding->setWindowColor( getWindowMap(7,5), 255,255,255);
				myBuilding->setWindowColor( getWindowMap(8,5), 255,255,255);
				myBuilding->setWindowColor( getWindowMap(9,4), 255,255,255);
				myBuilding->setWindowColor( getWindowMap(9,5), 255,255,255);
				myBuilding->setWindowColor( getWindowMap(10,4), 255,255,255);
				myBuilding->setWindowColor( getWindowMap(11,4), 255,255,255);
				myBuilding->setWindowColor( getWindowMap(11,5), 255,255,255);
			}else if(startAnimation_CountDown < 15 && startAnimation_CountDown >0 )
			{
				myBuilding->setWindowColor( getWindowMap(13,5), 255,255,255);
				myBuilding->setWindowColor( getWindowMap(14,5), 255,255,255);
				myBuilding->setWindowColor( getWindowMap(15,5), 255,255,255);
				myBuilding->setWindowColor( getWindowMap(16,5), 255,255,255);
			}

			if(startAnimation_CountDown ==0)
			{
				isGameStart = true;
				cout << "start game" << endl;
				for(int h=0; h < 10; h++){
					if(getWindowMap(21,h)!=-1)myBuilding->setWindowColor( getWindowMap(21,h), 255,255,255);
					if(getWindowMap(21,h)!=-1)myBuilding->setWindowColor( getWindowMap(22,h), 255,255,255);
				}
				mySoundManager->startStop();
				mySoundManager->background();
			}
		}

		// checking if this game is over
		// by points 
		if( pointsTeamA==18 && !isGameOver ){ gameOver = 'a'; speedRefresh= 5;mySoundManager->end();mySoundManager->backgroundStop();isGameOver = true; }
		if( pointsTeamB==18 && !isGameOver ){ gameOver = 'b'; speedRefresh= 5;mySoundManager->end();mySoundManager->backgroundStop();isGameOver = true; }
		// by users (only one from one team)
		if( getTotalLifePlayersTeamB()==0 && !isGameOver){ gameOver = 'a'; speedRefresh= 5;mySoundManager->end();mySoundManager->backgroundStop();isGameOver = true; }
		if( getTotalLifePlayersTeamA()==0 && !isGameOver){ gameOver = 'b'; speedRefresh= 5;mySoundManager->end();mySoundManager->backgroundStop();isGameOver = true; }
		
		// [State 2]: lets play !!
		if( startAnimation && isGameStart && !isGameOver  )
		{
			list<block>::iterator i;
			list<block>::iterator j;

			// block movement
			bool deleteItem = false;
			for(i=L.begin(); i != L.end();)
			{ 
				if( (*i).team != 'c' )
				{
					(*i).x +=  (*i).direction * 1;
					if( (*i).x>39 ){ (*i).x=0;  }
					if( (*i).x<0  ){ (*i).x=39; }
				}

				if( (*i).x !=4 && (*i).x !=5  )
				{
					deleteItem = false;

					// clean deaths blocks
					if( (*i).team == 'c')
					{ 
						if((*i).lifeCounter > 0){
							(*i).lifeCounter -=1;
						}else{					
							i = L.erase(i); 
							deleteItem = true; 
							points = true; 
						}
					}else{
						for(j=L.begin(); j != L.end(); ++j)
						{
							if((*i).x == (*j).x &&  (*i).y == (*j).y && (*j).team != (*i).team )
							{
								(*i).team = 'c';
								(*i).lifeCounter = 10;
								(*j).team = 'c';
								(*j).lifeCounter = 10;
								collision = true;
								// activate collisions sound
								
							}
						}

					}


				// when one team score point
				}else{
					if( (*i).x ==5 && (*i).team == 'a'  ){ i = L.erase(i); pointsTeamA +=1; }
					else if( (*i).x ==4 && (*i).team == 'b'  ){ i = L.erase(i); pointsTeamB +=1; }

					points = true;
					deleteItem = true;
					mySoundManager->collisions(' ');
				}

				//
				if( !points )
				{
					if((*i).team == 'a' && getWindowMap((*i).y,(*i).x)!=-1) myBuilding->setWindowColor( getWindowMap((*i).y,(*i).x), 0,255,0);
					if((*i).team == 'b' && getWindowMap((*i).y,(*i).x)!=-1) myBuilding->setWindowColor( getWindowMap((*i).y,(*i).x), 255,0,0);
					if((*i).team == 'c' && getWindowMap((*i).y,(*i).x)!=-1) myBuilding->setWindowColor( getWindowMap((*i).y,(*i).x), (int)(255.0f*( (float)(*i).lifeCounter /(float)10 )),(int)(255.0f*( (float)(*i).lifeCounter /(float)10 )),(int)(255.0f*( (float)(*i).lifeCounter /(float)10 )));
				} 
				if(!deleteItem)++i;
			}
		
			//points background
			for(int h=0; h < 18; h++) myBuilding->setWindowColor( getWindowMap(18-h,5), 20,20,200);
			for(int h=0; h < 18; h++) myBuilding->setWindowColor( getWindowMap(18-h,4), 20,20,200);

			//points display
			for(int h=0; h <pointsTeamA; h++) myBuilding->setWindowColor( getWindowMap(18-h,5), 0,255,0);
			for(int h=0; h <pointsTeamB; h++) myBuilding->setWindowColor( getWindowMap(18-h,4), 255,0,0);

		}
		// [state 3]: game Over
		if( isGameOver && startAnimation && isGameStart )
		{
			//End game
			//points display
			for(int h=0; h <pointsTeamA; h++) myBuilding->setWindowColor( getWindowMap(18-h,5), 0,255,0);
			for(int h=0; h <pointsTeamB; h++) myBuilding->setWindowColor( getWindowMap(18-h,4), 255,0,0);

			if( gameOverSnake < (21*40) ) gameOverSnake+=40;
			for(int h=0; h <gameOverSnake; h++)
			{
				cout << h/40<< " - "<< h%40 << endl;

				if( gameOver == 'a' && getWindowMap(h/40,h%40)!=-1 ) myBuilding->setWindowColor( getWindowMap(h/40,h%40), 0,255,0); 
				if( gameOver == 'b' && getWindowMap(h/40,h%40)!=-1 ) myBuilding->setWindowColor( getWindowMap(h/40,h%40), 255,0,0);
			}
		}		
		// ----------------------------------------------
		// rendering extras :: a blue line bottom building
		for( int g=0; g <40; g++ )
		{
			if( getWindowMap(19,g)!=-1){
				myBuilding->setWindowColor( getWindowMap(19,g), 0,0,255);
			}
			if( getWindowMap(20,g)!=-1){
				myBuilding->setWindowColor( getWindowMap(20,g), 0,0,255);
			}
		}
}

//-----------------------------
void gamePlay::sendData()
{
	myBuilding->flush();
}
//-----------------------------
// look is some player is been kill
bool gamePlay::getIsKilled(int posX,int posY, int playerTeam)
{
	bool isKill = false;
	list<block>::iterator j;
	char playerTeamChar;
	if(playerTeam==1){playerTeamChar='a';}else{playerTeamChar='b';}
	for(j=L.begin(); j != L.end(); ++j)
	{
		if((*j).x == posX &&  (*j).y == posY && (*j).team != playerTeamChar )
		{
			isKill = true; 
			(*j).team = 'c';
			(*j).lifeCounter = 10;
			break;
		}
	}
	return isKill;
}
//-----------------------------
// map main building windows
int  gamePlay::getWindowMap( int y, int x)
{
	if(y>22 || y<0 || x>39 || x<0 ) return -1;
	return windowAddrsTempExt[y][x];
}
// ----------------------------------------
// setter and getters
// ----------------------------------------

int gamePlay::getTotalLifePlayersTeamA()
{
	return totalLifePlayersTeamA;
}
//-----------------------------
int gamePlay::getTotalLifePlayersTeamB()
{
	return totalLifePlayersTeamB;
}
//-----------------------------
void  gamePlay::setTotalLifePlayersTeamA(int val)
{
	totalLifePlayersTeamA = val;
}
//-----------------------------
void  gamePlay::setTotalLifePlayersTeamB(int val)
{
	totalLifePlayersTeamB = val;
}

//-----------------------------
bool gamePlay::getIsGameStart()
{
	return isGameStart;
}
//-----------------------------
void  gamePlay::setPuntosA(int val)
{
	mySoundManager->score(1);
	pointsTeamA = val;
}
//-----------------------------
void  gamePlay::setPuntosB(int val)
{
	mySoundManager->score(2);
	pointsTeamB = val;	
}
//-----------------------------
int  gamePlay::getPointsTeamA()
{
	return pointsTeamA;
}
//-----------------------------
int  gamePlay::getPointsTeamB()
{
	return pointsTeamB;
}
//-----------------------------
bool gamePlay::getIsGameOver()
{
	return isGameOver;
}
//-----------------------------
int gamePlay::getTotalWidthWindows()
{
	return totalWindowsWidth;
}
//-----------------------------
int gamePlay::getTotalHeightWindows()
{
	return totalWindowsHeight;

}
//-----------------------------
ofColor gamePlay::getWindowColor(int posX,int posY)
{
	ofColor out;
	int address = getWindowMap(posX,posY );
	if(address!=-1){ 
		out = myBuilding->getWindowColor( address);
	}else{
		out.r = 0;
		out.g = 0;
		out.b = 0;
	}
	return out;
}
// ----------------------------------------
// render methods
//-----------------------------
void  gamePlay::lightWindow(int posX,int posY, int val)
{
	myBuilding->setWindowColor( getWindowMap(posY,posX), val,val,val);		
}
//-----------------------------
void  gamePlay::lightColorWindow(int posX,int posY, int R, int G, int B)
{
	myBuilding->setWindowColor( getWindowMap(posY,posX), R,G,B);		
}
//-----------------------------
void  gamePlay::cleanColor(){
	myBuilding->cleanColor();
}
//-----------------------------
